<template>
  <div>
    <DynamicTable
      row-key="id"
      header-title="课程管理"
      :data-request="Api.student.coursePage"
      :columns="columns"
      bordered
      size="small"
    >
      <template #toolbar>
        <a-button type="primary" @click="openCourseModal({})"> 新增 </a-button>
      </template>
    </DynamicTable>

    <a-modal v-model:visible="qrcodeVisible" title="签到二维码" width="400px" :footer="null">
      <div class="qrcode-container">
        <QrcodeVue :value="currentQrcode" :size="300" :background="'#ffffff'" :level="'H'" />
      </div>
    </a-modal>

    <a-modal v-model:visible="locationVisible" title="位置信息" width="400px" :footer="null">
      <div class="location-container">
        <p>当前位置坐标：</p>
        <p>纬度：{{ currentLocation.latitude }}</p>
        <p>经度：{{ currentLocation.longitude }}</p>
        <a-button type="primary" class="location-set-btn" @click="handleSetLocation"
          >设置为签到位置</a-button
        >
      </div>
    </a-modal>

    <a-modal v-model:visible="gestureVisible" title="手势签到" width="400px" :footer="null">
      <div class="gesture-container">
        <GestureGrid v-model:value="currentGesture" @save="handleGestureSave" />
      </div>
    </a-modal>

    <a-modal v-model:visible="checkStatVisible" title="签到情况统计" width="800px" :footer="null">
      <a-modal v-model:visible="statusModalVisible" title="修改用户状态" @ok="handleStatusChange">
        <a-radio-group v-model:value="selectedStatus">
          <a-radio v-for="option in statusOptions" :key="option.value" :value="option.value">
            {{ option.label }}
          </a-radio>
        </a-radio-group>
      </a-modal>
      <div class="check-stat-header">
        <div class="header-actions">
          <a-date-picker
            v-model:value="checkDate"
            :format="'YYYY-MM-DD'"
            @change="handleDateChange"
          />
          <a-button type="primary" @click="handleExportData(currentCourse)">导出</a-button>
        </div>
        <a-tabs v-model:activeKey="activeTabKey">
          <a-tab-pane key="all" tab="全部">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.all"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="checked" tab="已签到">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.checked"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="unchecked" tab="未签到">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.unchecked"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="late" tab="迟到">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.late"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="absent" tab="旷课">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.absent"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
          <a-tab-pane key="leave" tab="请假">
            <div class="student-list">
              <div
                v-for="item in checkStatData?.leave"
                :key="item.id"
                class="student-item"
                @click="openStatusModal(item)"
              >
                <a-avatar :src="item.avatar" shape="circle" />
                <span class="student-name">{{ item.userName }}</span>
              </div>
            </div>
          </a-tab-pane>
        </a-tabs>
      </div>
    </a-modal>
  </div>
</template>

<script lang="ts" setup>
  import { ref, onMounted } from 'vue';
  import dayjs from 'dayjs';
  import QrcodeVue from 'qrcode.vue';
  import type { TableColumn } from '@/components/core/dynamic-table';
  import GestureGrid from '@/components/business/GestureGrid/index.vue';

  import { useTable } from '@/components/core/dynamic-table';
  import { useFormModal } from '@/hooks/useModal/';
  import Api from '@/api/';
  import { formatToDateTime } from '@/utils/dateUtil';

  import './courses.less';

  defineOptions({
    name: 'StudentCourses',
  });

  interface TableListItem {
    id: number;
    name: string;
    createTime: string;
    classesId: number;
  }

  interface StudentItem {
    userId: number;
    userName: string;
    avatar: string;
    checkStatus: number;
    checkDate: string;
  }

  const [DynamicTable, dynamicTableInstance] = useTable({
    pagination: {
      pageSize: 10,
      showSizeChanger: true,
      showQuickJumper: true,
    },
  });
  const [showModal] = useFormModal();
  const checkStatVisible = ref(false);
  const statusModalVisible = ref(false);
  const qrcodeVisible = ref(false);
  const currentQrcode = ref('');
  const gestureVisible = ref(false);
  const currentGesture = ref('');
  const currentCourseForGesture = ref<TableListItem | null>(null);
  const locationVisible = ref(false);
  const currentLocation = ref({ latitude: 0, longitude: 0 });
  const currentCourseForLocation = ref<TableListItem | null>(null);

  const handleSetLocation = async () => {
    try {
      if (!currentCourseForLocation.value) return;

      await Api.student.courseLocationUpdate({
        id: currentCourseForLocation.value.id,
        lat: currentLocation.value.latitude.toString(),
        lon: currentLocation.value.longitude.toString(),
      });

      locationVisible.value = false;
      currentCourseForLocation.value = null;
      dynamicTableInstance?.reload();
      window.$message.success('签到位置设置成功');
    } catch (error) {
      console.error('设置签到位置失败:', error);
      window.$message.error('设置签到位置失败');
    }
  };
  const activeTabKey = ref('all');
  const currentCourse = ref<TableListItem | null>(null);
  const currentStudent = ref<StudentItem | null>(null);
  const checkDate = ref(dayjs());
  const statusOptions = [
    { label: '未签到', value: 0 },
    { label: '已签到', value: 1 },
    { label: '迟到', value: 2 },
    { label: '旷课', value: 3 },
    { label: '请假', value: 4 },
  ];
  const selectedStatus = ref<number>();
  const checkStatData = ref<{
    all: StudentItem[];
    checked: StudentItem[];
    unchecked: StudentItem[];
    late: StudentItem[];
    absent: StudentItem[];
    leave: StudentItem[];
  } | null>(null);

  const weekMap = {
    1: '星期一',
    2: '星期二',
    3: '星期三',
    4: '星期四',
    5: '星期五',
    6: '星期六',
    7: '星期天',
  };

  const checkMap = {
    1: '直接签到',
    2: '人脸签到',
    3: '二维码签到',
    4: '定位签到',
    5: '手势签到',
  };

  const handleGestureSave = async (gesture: string) => {
    console.log('保存手势', gesture);
    try {
      if (!currentCourseForGesture.value) return;

      currentCourseForGesture.value.checkContent = gesture;

      await Api.student.courseUpdate(currentCourseForGesture.value);

      gestureVisible.value = false;
      currentCourseForGesture.value = null;
      dynamicTableInstance?.reload();
    } catch (error) {
      console.error('设置手势失败:', error);
    }
  };

  const classList = ref([]);

  onMounted(async () => {
    const data = await Api.student.classList({});
    classList.value = data;
  });

  const formSchemas = [
    {
      field: 'courseName',
      label: '课程名称',
      component: 'Input',
      required: true,
    },
    {
      field: 'classesId',
      label: '班级',
      component: 'Select',
      required: true,
      componentProps: {
        options: classList,
        fieldNames: {
          label: 'className',
          value: 'id',
        },
      },
    },
    {
      field: 'weekDay',
      label: '星期',
      component: 'Select',
      required: true,
      componentProps: {
        options: Object.entries(weekMap).map(([value, label]) => ({
          value: Number(value),
          label,
        })),
      },
    },
    {
      field: 'checkType',
      label: '签到类型',
      component: 'Select',
      required: true,
      componentProps: {
        options: Object.entries(checkMap).map(([value, label]) => ({
          value: Number(value),
          label,
        })),
      },
    },
    {
      field: 'startTime',
      label: '开始时间',
      component: 'TimePicker',
      required: true,
      componentProps: {
        format: 'HH:mm',
        valueFormat: 'HH:mm',
      },
    },
    {
      field: 'endTime',
      label: '结束时间',
      component: 'TimePicker',
      required: true,
      componentProps: {
        format: 'HH:mm',
        valueFormat: 'HH:mm',
      },
    },
    {
      field: 'checkContent',
      label: '二维码或手势',
      component: 'Input',
    },
    {
      field: 'lat',
      label: '纬度',
      component: 'Input',
    },
    {
      field: 'lon',
      label: '经度',
      component: 'Input',
    },
  ];

  /**
   * @description 打开新增/编辑弹窗
   */
  const openCourseModal = async (record: Partial<TableListItem>) => {
    const [formRef] = await showModal({
      modalProps: {
        title: `${record.id ? '编辑' : '新增'}课程`,
        width: '50%',
        onFinish: async (values) => {
          if (record.id) {
            await Api.student.courseUpdate({ id: record.id, ...values });
          } else {
            await Api.student.courseCreate(values);
          }
          dynamicTableInstance?.reload();
        },
      },
      formProps: {
        labelWidth: 100,
        schemas: formSchemas,
      },
    });
    formRef?.setFieldsValue(record);
  };

  const delRowConfirm = async (record: TableListItem) => {
    await Api.studentCourses.courseDelete({ id: record.id });
    dynamicTableInstance?.reload();
  };

  const handleDateChange = async () => {
    if (currentCourse.value) {
      await fetchCheckStatData(currentCourse.value);
    }
  };

  const fetchCheckStatData = async (record: TableListItem) => {
    try {
      const data = await Api.user.checkStat({
        checkDate: checkDate.value.format('YYYY-MM-DD'),
        classesId: record.classesId,
        courseId: record.id,
      });

      // 根据签到状态分类学生数据
      const processedData = {
        all: data,
        checked: data.filter((item) => item.checkStatus === 1),
        unchecked: data.filter((item) => item.checkStatus === 0),
        late: data.filter((item) => item.checkStatus === 2),
        absent: data.filter((item) => item.checkStatus === 3),
        leave: data.filter((item) => item.checkStatus === 4),
      };

      checkStatData.value = processedData;
    } catch (error) {
      console.error('获取签到统计数据失败:', error);
    }
  };

  const openCheckStatModal = async (record: TableListItem) => {
    currentCourse.value = record;
    checkStatVisible.value = true;
    await fetchCheckStatData(record);
  };

  const handleExportData = async (record: TableListItem) => {
    try {
      if (!checkStatData.value) return;

      // 准备CSV数据
      const statusMap = {
        0: '未签到',
        1: '已签到',
        2: '迟到',
        3: '旷课',
        4: '请假',
      };

      const csvData = checkStatData.value.all.map((student) => [
        student.checkDate,
        student.userName,
        statusMap[student.checkStatus] || '未知状态',
        currentCourse.value?.courseName || '',
      ]);

      // 添加表头
      csvData.unshift(['签到时间', '学生姓名', '签到状态', '课程名称']);

      // 生成CSV内容
      const csvContent = csvData.map((row) => row.join(',')).join('\n');

      // 创建Blob对象
      const blob = new Blob([new Uint8Array([0xef, 0xbb, 0xbf]), csvContent], {
        type: 'text/csv;charset=utf-8',
      });

      // 创建下载链接
      const link = document.createElement('a');
      link.href = URL.createObjectURL(blob);
      link.download = `签到统计_${checkDate.value.format('YYYY-MM-DD')}.csv`;

      // 触发下载
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    } catch (error) {
      console.error('导出签到统计数据失败:', error);
    }
  };

  const openStatusModal = (student: StudentItem) => {
    currentStudent.value = student;
    selectedStatus.value = student.checkStatus;
    statusModalVisible.value = true;
  };

  const handleStatusChange = async () => {
    if (!currentStudent.value || !selectedStatus.value) return;

    try {
      await Api.check.changeStatus({
        checkDate: checkDate.value.format('YYYY-MM-DD'),
        userId: currentStudent.value.userId,
        courseId: currentCourse.value!.id,
        checkStatus: selectedStatus.value,
      });
      statusModalVisible.value = false;
      await fetchCheckStatData(currentCourse.value!);
    } catch (error) {
      console.error('更新用户状态失败:', error);
    }
  };

  const columns: TableColumn<TableListItem>[] = [
    {
      title: '课程ID',
      dataIndex: 'id',
      width: 80,
      hideInSearch: true,
    },
    {
      title: '课程名称',
      dataIndex: 'courseName',
    },
    {
      title: '班级',
      dataIndex: 'classesId',
      customRender: ({ text }) => {
        const classItem = classList.value.find((item) => item.id === text);
        return classItem?.className || text;
      },
      formItemProps: {
        component: 'Select',
        componentProps: {
          options: classList,
          fieldNames: {
            label: 'className',
            value: 'id',
          },
        },
      },
    },
    {
      title: '星期',
      dataIndex: 'weekDay',
      customRender: ({ text }) => {
        return weekMap[text] || text;
      },
      formItemProps: {
        component: 'Select',
        componentProps: {
          options: Object.entries(weekMap).map(([value, label]) => ({
            value: Number(value),
            label,
          })),
        },
      },
    },
    {
      title: '签到类型',
      dataIndex: 'checkType',
      customRender: ({ text }) => {
        return checkMap[text] || text;
      },
      formItemProps: {
        component: 'Select',
        componentProps: {
          options: Object.entries(checkMap).map(([value, label]) => ({
            value: Number(value),
            label,
          })),
        },
      },
    },
    {
      title: '开始时间',
      dataIndex: 'startTime',
      hideInSearch: true,
    },
    {
      title: '结束时间',
      dataIndex: 'endTime',
      hideInSearch: true,
    },
    {
      title: '创建时间',
      dataIndex: 'createTime',
      width: 180,
      hideInSearch: true,
      customRender: ({ text }) => formatToDateTime(text),
    },
    {
      title: '操作',
      width: 160,
      dataIndex: 'ACTION',
      hideInSearch: true,
      fixed: 'right',
      actions: ({ record }) => [
        record.checkType === 3 && {
          label: '二维码',
          onClick: async () => {
            if (!record.checkContent) {
              return;
            }
            currentQrcode.value = record.checkContent;
            qrcodeVisible.value = true;
          },
        },
        record.checkType === 5 && {
          label: '手势',
          onClick: () => {
            currentCourseForGesture.value = record;
            currentGesture.value = record.gesture || '';
            gestureVisible.value = true;
          },
        },
        record.checkType === 4 && {
          label: '定位',
          onClick: async () => {
            currentCourseForLocation.value = record;
            if (navigator.geolocation) {
              navigator.geolocation.getCurrentPosition(
                (position) => {
                  currentLocation.value = {
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                  };
                  locationVisible.value = true;
                },
                (error) => {
                  console.error('获取位置信息失败:', error);
                },
              );
            } else {
              console.error('浏览器不支持地理定位');
            }
          },
        },
        {
          label: '签到情况',
          onClick: () => openCheckStatModal(record),
        },
        {
          label: '编辑',
          onClick: () => openCourseModal(record),
        },
        // {
        //   label: '删除',
        //   popConfirm: {
        //     title: '你确定要删除吗？',
        //     placement: 'left',
        //     onConfirm: () => delRowConfirm(record),
        //   },
        // },
      ],
    },
  ];
</script>

<style lang="less" scoped>
  .qrcode-container {
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
  }

  .location-container {
    padding: 20px;

    p {
      margin-bottom: 10px;
      font-size: 16px;
    }

    .location-set-btn {
      width: 100%;
      margin-top: 16px;
    }
  }

  .check-stat-header {
    display: flex;
    flex-direction: column;
    gap: 16px;

    .header-actions {
      display: flex;
      align-items: center;
      gap: 16px;
      align-self: flex-end;
    }
  }

  .student-list {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    padding: 16px;
  }

  .student-item {
    display: flex;
    align-items: center;
    padding: 8px;
    transition: all 0.3s;
    border-radius: 8px;
    background-color: #f5f5f5;
    gap: 8px;

    &:hover {
      background-color: #e6f7ff;
    }

    .student-name {
      color: #333;
      font-size: 14px;
    }
  }
</style>
